home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / InstrObject.c < prev    next >
Text File  |  1994-08-15  |  19KB  |  656 lines

  1. /* InstrObject.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "InstrObject.h"
  31. #include "InstrWindow.h"
  32. #include "InstrList.h"
  33. #include "Memory.h"
  34. #include "DataMunging.h"
  35. #include "BuildInstrument.h"
  36. #include "InstrumentStructure.h"
  37. #include "DataMunging.h"
  38. #include "Numbers.h"
  39. #include "Alert.h"
  40. #include "BufferedFileInput.h"
  41. #include "BufferedFileOutput.h"
  42.  
  43.  
  44. struct InstrObjectRec
  45.     {
  46.         MyBoolean                                DataModified;
  47.  
  48.         char*                                        Name;
  49.  
  50.         char*                                        InstrDefinition;
  51.         InstrumentRec*                    BuiltInstrument; /* NIL = not built */
  52.         MyBoolean                                UpToDate;
  53.  
  54.         InstrWindowRec*                    InstrWindow;
  55.  
  56.         struct CodeCenterRec*        CodeCenter;
  57.         struct MainWindowRec*        MainWindow;
  58.         InstrListRec*                        InstrList;
  59.  
  60.         short                                        SavedWindowXLoc;
  61.         short                                        SavedWindowYLoc;
  62.         short                                        SavedWindowWidth;
  63.         short                                        SavedWindowHeight;
  64.     };
  65.  
  66.  
  67. /* create a new empty instrument object */
  68. InstrObjectRec*                NewInstrObject(struct CodeCenterRec* CodeCenter,
  69.                                                 struct MainWindowRec* MainWindow, struct InstrListRec* InstrList)
  70.     {
  71.         InstrObjectRec*            InstrObj;
  72.  
  73.         InstrObj = (InstrObjectRec*)AllocPtrCanFail(sizeof(InstrObjectRec),"InstrObjectRec");
  74.         if (InstrObj == NIL)
  75.             {
  76.              FailurePoint1:
  77.                 return NIL;
  78.             }
  79.         InstrObj->Name = StringToBlockCopy("untitled");
  80.         if (InstrObj->Name == NIL)
  81.             {
  82.              FailurePoint2:
  83.                 ReleasePtr((char*)InstrObj);
  84.                 goto FailurePoint1;
  85.             }
  86.         InstrObj->InstrDefinition = AllocPtrCanFail(0,"InstrDefinition");
  87.         if (InstrObj->InstrDefinition == NIL)
  88.             {
  89.              FailurePoint3:
  90.                 ReleasePtr(InstrObj->Name);
  91.                 goto FailurePoint2;
  92.             }
  93.         InstrObj->CodeCenter = CodeCenter;
  94.         InstrObj->MainWindow = MainWindow;
  95.         InstrObj->InstrList = InstrList;
  96.         InstrObj->DataModified = False;
  97.         InstrObj->InstrWindow = NIL;
  98.         InstrObj->BuiltInstrument = NIL;
  99.         InstrObj->UpToDate = False;
  100.         InstrObj->SavedWindowXLoc = 0;
  101.         InstrObj->SavedWindowYLoc = 0;
  102.         InstrObj->SavedWindowWidth = 0;
  103.         InstrObj->SavedWindowHeight = 0;
  104.         return InstrObj;
  105.     }
  106.  
  107.  
  108. /* dispose of instrument object and all the crud it contains */
  109. void                                    DisposeInstrObject(InstrObjectRec* InstrObj)
  110.     {
  111.         CheckPtrExistence(InstrObj);
  112.         if (InstrObj->InstrWindow != NIL)
  113.             {
  114.                 DisposeInstrWindow(InstrObj->InstrWindow);
  115.                 ERROR(InstrObj->InstrWindow != NIL,PRERR(ForceAbort,
  116.                     "DisposeInstrObject:  disposed window but window isn't NIL"));
  117.             }
  118.         if (InstrObj->BuiltInstrument != NIL)
  119.             {
  120.                 DisposeInstrumentSpecification(InstrObj->BuiltInstrument);
  121.             }
  122.         ReleasePtr(InstrObj->Name);
  123.         ReleasePtr(InstrObj->InstrDefinition);
  124.         ReleasePtr((char*)InstrObj);
  125.     }
  126.  
  127.  
  128. /* find out if the object has been changed */
  129. MyBoolean                            HasInstrObjectBeenModified(InstrObjectRec* InstrObj)
  130.     {
  131.         CheckPtrExistence(InstrObj);
  132.         if (InstrObj->InstrWindow != NIL)
  133.             {
  134.                 return InstrObj->DataModified
  135.                     || HasInstrWindowBeenModified(InstrObj->InstrWindow);
  136.             }
  137.          else
  138.             {
  139.                 return InstrObj->DataModified;
  140.             }
  141.     }
  142.  
  143.  
  144. /* indicate that object has been modified */
  145. void                                    InstrObjHasBeenModified(InstrObjectRec* InstrObj)
  146.     {
  147.         CheckPtrExistence(InstrObj);
  148.         InstrObj->DataModified = True;
  149.         InstrObj->UpToDate = False;
  150.     }
  151.  
  152.  
  153. /* unbuild the instrument */
  154. void                                    UnbuildInstrObject(InstrObjectRec* InstrObj)
  155.     {
  156.         CheckPtrExistence(InstrObj);
  157.         InstrObj->UpToDate = False;
  158.         if (InstrObj->BuiltInstrument != NIL)
  159.             {
  160.                 DisposeInstrumentSpecification(InstrObj->BuiltInstrument);
  161.                 InstrObj->BuiltInstrument = NIL;
  162.             }
  163.     }
  164.  
  165.  
  166. /* build the instrument.  returns True if successful */
  167. MyBoolean                            BuildInstrObject(InstrObjectRec* InstrObj)
  168.     {
  169.         char*                                InstrText;
  170.         BuildInstrErrors        Error;
  171.         long                                ErrorLine;
  172.         InstrumentRec*            TheInstrument;
  173.  
  174.         CheckPtrExistence(InstrObj);
  175.         UnbuildInstrObject(InstrObj);
  176.         InstrText = InstrObjectGetDefinitionCopy(InstrObj);
  177.         if (InstrText == NIL)
  178.             {
  179.                 AlertHalt("There is not enough memory available to build instrument "
  180.                     "definition.",NIL);
  181.                 return False;
  182.             }
  183.         Error = BuildInstrumentFromText(InstrText,&ErrorLine,&TheInstrument,
  184.             MainWindowGetSampleList(InstrObj->MainWindow),MainWindowGetAlgoSampList(
  185.             InstrObj->MainWindow),MainWindowGetWaveTableList(InstrObj->MainWindow),
  186.             MainWindowGetAlgoWaveTableList(InstrObj->MainWindow));
  187.         ReleasePtr(InstrText);
  188.         if (Error != eBuildInstrNoError)
  189.             {
  190.                 if (!InstrObjectOpenWindow(InstrObj))
  191.                     {
  192.                      CouldntShowErrorPoint:
  193.                         AlertHalt("An error occurred while compiling the instrument definition, "
  194.                             "but there is not enough memory available to open the window.",NIL);
  195.                     }
  196.                  else
  197.                     {
  198.                         char*                                ErrorString;
  199.                         MyBoolean                        SuccessFlag;
  200.  
  201.                         BringInstrWindowToFront(InstrObj->InstrWindow);
  202.                         InstrWindowHilightLine(InstrObj->InstrWindow,ErrorLine - 1);
  203.                         /* figure out what the error string is */
  204.                         SuccessFlag = False;
  205.                         ErrorString = StringFromRaw(BuildInstrGetErrorMessageText(Error));
  206.                         if (ErrorString != NIL)
  207.                             {
  208.                                 char*                                NumberString;
  209.  
  210.                                 NumberString = IntegerToString(ErrorLine);
  211.                                 if (NumberString != NIL)
  212.                                     {
  213.                                         char*                                Key;
  214.  
  215.                                         Key = StringToBlockCopy("_");
  216.                                         if (Key != NIL)
  217.                                             {
  218.                                                 char*                                BaseMessage;
  219.  
  220.                                                 BaseMessage = StringFromRaw("Error on line _:  _");
  221.                                                 if (BaseMessage != NIL)
  222.                                                     {
  223.                                                         char*                                FixedMessage;
  224.  
  225.                                                         FixedMessage = ReplaceBlockCopy(BaseMessage,Key,NumberString);
  226.                                                         if (FixedMessage != NIL)
  227.                                                             {
  228.                                                                 AlertHalt(FixedMessage,ErrorString);
  229.                                                                 ReleasePtr(FixedMessage);
  230.                                                                 SuccessFlag = True;
  231.                                                             }
  232.                                                         ReleasePtr(BaseMessage);
  233.                                                     }
  234.                                                 ReleasePtr(Key);
  235.                                             }
  236.                                         ReleasePtr(NumberString);
  237.                                     }
  238.                                 ReleasePtr(ErrorString);
  239.                             }
  240.                         if (!SuccessFlag)
  241.                             {
  242.                                 goto CouldntShowErrorPoint;
  243.                             }
  244.                     }
  245.                 return False;
  246.             }
  247.         InstrObj->BuiltInstrument = TheInstrument;
  248.         InstrObj->UpToDate = True;
  249.         return True;
  250.     }
  251.  
  252.  
  253. /* make instrument up to date */
  254. MyBoolean                            MakeInstrObjectUpToDate(InstrObjectRec* InstrObj)
  255.     {
  256.         CheckPtrExistence(InstrObj);
  257.         if (!InstrObj->UpToDate || (InstrObj->InstrWindow != NIL))
  258.             {
  259.                 return BuildInstrObject(InstrObj);
  260.             }
  261.          else
  262.             {
  263.                 return True;
  264.             }
  265.     }
  266.  
  267.  
  268. /* find out if the instrument object is up to date */
  269. MyBoolean                            IsIntrumentObjectUpToDate(InstrObjectRec* InstrObj)
  270.     {
  271.         CheckPtrExistence(InstrObj);
  272.         ERROR(InstrObj->UpToDate && (InstrObj->BuiltInstrument == NIL),PRERR(ForceAbort,
  273.             "IsIntrumentObjectUpToDate:  build instrument inconsistency"));
  274.         return InstrObj->UpToDate;
  275.     }
  276.  
  277.  
  278. /* get the definition of the instrument */
  279. struct InstrumentRec*    GetInstrObjectRawData(InstrObjectRec* InstrObj)
  280.     {
  281.         CheckPtrExistence(InstrObj);
  282.         if (!MakeInstrObjectUpToDate(InstrObj))
  283.             {
  284.                 return NIL;
  285.             }
  286.          else
  287.             {
  288.                 return InstrObj->BuiltInstrument;
  289.             }
  290.     }
  291.  
  292.  
  293. /* get a copy of the instrument's name */
  294. char*                                    InstrObjectGetNameCopy(InstrObjectRec* InstrObj)
  295.     {
  296.         CheckPtrExistence(InstrObj);
  297.         if (InstrObj->InstrWindow != NIL)
  298.             {
  299.                 return InstrWindowGetNameCopy(InstrObj->InstrWindow);
  300.             }
  301.          else
  302.             {
  303.                 return CopyPtr(InstrObj->Name);
  304.             }
  305.     }
  306.  
  307.  
  308. /* install a new name.  the object becomes the owner of the name */
  309. void                                    InstrObjectPutName(InstrObjectRec* InstrObj, char* Name)
  310.     {
  311.         CheckPtrExistence(InstrObj);
  312.         CheckPtrExistence(Name);
  313.         ReleasePtr(InstrObj->Name);
  314.         InstrObj->Name = Name;
  315.         InstrObj->DataModified = True;
  316.         InstrObj->UpToDate = False;
  317.         InstrListInstrNameChanged(InstrObj->InstrList,InstrObj);
  318.     }
  319.  
  320.  
  321. /* get the text definition of the object */
  322. char*                                    InstrObjectGetDefinitionCopy(InstrObjectRec* InstrObj)
  323.     {
  324.         CheckPtrExistence(InstrObj);
  325.         if (InstrObj->InstrWindow != NIL)
  326.             {
  327.                 return InstrWindowGetDefinitionCopy(InstrObj->InstrWindow);
  328.             }
  329.          else
  330.             {
  331.                 return CopyPtr(InstrObj->InstrDefinition);
  332.             }
  333.     }
  334.  
  335.  
  336. /* put a new definition of the instrument.  it becomes owner of the block */
  337. void                                    InstrObjectPutDefinition(InstrObjectRec* InstrObj, char* NewDef)
  338.     {
  339.         CheckPtrExistence(InstrObj);
  340.         CheckPtrExistence(NewDef);
  341.         ReleasePtr(InstrObj->InstrDefinition);
  342.         InstrObj->InstrDefinition = NewDef;
  343.         InstrObj->DataModified = True;
  344.         InstrObj->UpToDate = False;
  345.         UnbuildInstrObject(InstrObj);
  346.     }
  347.  
  348.  
  349. /* display the editor window for this object or bring it to the top */
  350. MyBoolean                            InstrObjectOpenWindow(InstrObjectRec* InstrObj)
  351.     {
  352.         CheckPtrExistence(InstrObj);
  353.         if (InstrObj->InstrWindow == NIL)
  354.             {
  355.                 /* create window */
  356.                 InstrObj->InstrWindow = NewInstrWindow(InstrObj,InstrObj->MainWindow,
  357.                     InstrObj->InstrList,InstrObj->SavedWindowXLoc,InstrObj->SavedWindowYLoc,
  358.                     InstrObj->SavedWindowWidth,InstrObj->SavedWindowHeight);
  359.             }
  360.          else
  361.             {
  362.                 /* bring window to top */
  363.                 BringInstrWindowToFront(InstrObj->InstrWindow);
  364.             }
  365.         return (InstrObj->InstrWindow != NIL);
  366.     }
  367.  
  368.  
  369. /* notify the object that the window has disappeared.  The object does not */
  370. /* perform any actions */
  371. void                                    InstrObjectWindowCloseNotify(InstrObjectRec* InstrObj,
  372.                                                 short NewX, short NewY, short NewWidth, short NewHeight)
  373.     {
  374.         CheckPtrExistence(InstrObj);
  375.         ERROR(InstrObj->InstrWindow == NIL,PRERR(ForceAbort,
  376.             "InstrObjectWindowCloseNotify:  window is already NIL"));
  377.         InstrObj->InstrWindow = NIL;
  378.         InstrObj->SavedWindowXLoc = NewX;
  379.         InstrObj->SavedWindowYLoc = NewY;
  380.         InstrObj->SavedWindowWidth = NewWidth;
  381.         InstrObj->SavedWindowHeight = NewHeight;
  382.     }
  383.  
  384.  
  385. /* the document's name changed, so we need to update the window */
  386. void                                    InstrObjectGlobalNameChange(InstrObjectRec* InstrObj,
  387.                                                 char* NewFilename)
  388.     {
  389.         CheckPtrExistence(InstrObj);
  390.         if (InstrObj->InstrWindow != NIL)
  391.             {
  392.                 InstrWindowGlobalNameChange(InstrObj->InstrWindow,NewFilename);
  393.             }
  394.     }
  395.  
  396.  
  397. /* Instrument Object Subblock Format: */
  398. /*   1-byte format version number */
  399. /*       should be 1 */
  400. /*   2-byte little endian window X location (signed; origin at top-left of screen) */
  401. /*   2-byte little endian window Y location */
  402. /*   2-byte little endian window width */
  403. /*   2-byte little endian window height */
  404. /*   4-byte little endian name string length */
  405. /*   n-byte name string (line feed = 0x0a) */
  406. /*   4-byte little endian instrument definition length */
  407. /*   n-byte instrument definition string (line feed = 0x0a) */
  408.  
  409.  
  410. /* create a new object from data in the file. */
  411. FileLoadingErrors            InstrObjectNewFromFile(InstrObjectRec** ObjectOut,
  412.                                                 struct BufferedInputRec* Input, struct CodeCenterRec* CodeCenter,
  413.                                                 struct MainWindowRec* MainWindow, struct InstrListRec* InstrList)
  414.     {
  415.         signed long                    SignedLong;
  416.         signed short                SignedShort;
  417.         unsigned char                UnsignedChar;
  418.         FileLoadingErrors        Error;
  419.         InstrObjectRec*            InstrObj;
  420.  
  421.         CheckPtrExistence(Input);
  422.         CheckPtrExistence(CodeCenter);
  423.         CheckPtrExistence(MainWindow);
  424.         CheckPtrExistence(InstrList);
  425.  
  426.         InstrObj = (InstrObjectRec*)AllocPtrCanFail(sizeof(InstrObjectRec),"InstrObjectRec");
  427.         if (InstrObj == NIL)
  428.             {
  429.                 Error = eFileLoadOutOfMemory;
  430.              FailurePoint1:
  431.                 return Error;
  432.             }
  433.  
  434.         /*   1-byte format version number */
  435.         /*       should be 1 */
  436.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  437.             {
  438.                 Error = eFileLoadDiskError;
  439.              FailurePoint2:
  440.                 ReleasePtr((char*)InstrObj);
  441.                 goto FailurePoint1;
  442.             }
  443.         if (UnsignedChar != 1)
  444.             {
  445.                 Error = eFileLoadBadFormat;
  446.              FailurePoint3:
  447.                 goto FailurePoint2;
  448.             }
  449.  
  450.         /*   2-byte little endian window X location (signed; origin at top-left of screen) */
  451.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  452.             {
  453.                 Error = eFileLoadDiskError;
  454.              FailurePoint4:
  455.                 goto FailurePoint3;
  456.             }
  457.         InstrObj->SavedWindowXLoc = SignedShort;
  458.  
  459.         /*   2-byte little endian window Y location */
  460.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  461.             {
  462.                 Error = eFileLoadDiskError;
  463.              FailurePoint5:
  464.                 goto FailurePoint4;
  465.             }
  466.         InstrObj->SavedWindowYLoc = SignedShort;
  467.  
  468.         /*   2-byte little endian window width */
  469.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  470.             {
  471.                 Error = eFileLoadDiskError;
  472.              FailurePoint6:
  473.                 goto FailurePoint5;
  474.             }
  475.         InstrObj->SavedWindowWidth = SignedShort;
  476.  
  477.         /*   2-byte little endian window height */
  478.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  479.             {
  480.                 Error = eFileLoadDiskError;
  481.              FailurePoint7:
  482.                 goto FailurePoint6;
  483.             }
  484.         InstrObj->SavedWindowHeight = SignedShort;
  485.  
  486.         /*   4-byte little endian name string length */
  487.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  488.             {
  489.                 Error = eFileLoadDiskError;
  490.              FailurePoint8:
  491.                 goto FailurePoint7;
  492.             }
  493.         if (SignedLong < 0)
  494.             {
  495.                 Error = eFileLoadBadFormat;
  496.              FailurePoint9:
  497.                 goto FailurePoint8;
  498.             }
  499.  
  500.         /*   n-byte name string (line feed = 0x0a) */
  501.         InstrObj->Name = AllocPtrCanFail(SignedLong,"InstrObjectRec:  name");
  502.         if (InstrObj->Name == NIL)
  503.             {
  504.                 Error = eFileLoadOutOfMemory;
  505.              FailurePoint10:
  506.                 goto FailurePoint9;
  507.             }
  508.         if (!ReadBufferedInput(Input,SignedLong,InstrObj->Name))
  509.             {
  510.                 Error = eFileLoadDiskError;
  511.              FailurePoint11:
  512.                 ReleasePtr(InstrObj->Name);
  513.                 goto FailurePoint10;
  514.             }
  515.  
  516.         /*   4-byte little endian instrument definition length */
  517.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  518.             {
  519.                 Error = eFileLoadDiskError;
  520.              FailurePoint12:
  521.                 goto FailurePoint11;
  522.             }
  523.         if (SignedLong < 0)
  524.             {
  525.                 Error = eFileLoadBadFormat;
  526.              FailurePoint13:
  527.                 goto FailurePoint12;
  528.             }
  529.  
  530.         /*   n-byte instrument definition string (line feed = 0x0a) */
  531.         InstrObj->InstrDefinition = AllocPtrCanFail(SignedLong,"InstrObjectRec: definition");
  532.         if (InstrObj->InstrDefinition == NIL)
  533.             {
  534.                 Error = eFileLoadOutOfMemory;
  535.              FailurePoint14:
  536.                 goto FailurePoint13;
  537.             }
  538.         if (!ReadBufferedInput(Input,SignedLong,InstrObj->InstrDefinition))
  539.             {
  540.                 Error = eFileLoadDiskError;
  541.              FailurePoint15:
  542.                 ReleasePtr(InstrObj->InstrDefinition);
  543.                 goto FailurePoint14;
  544.             }
  545.  
  546.         /* fill in the other fields */
  547.         InstrObj->DataModified = False;
  548.         InstrObj->BuiltInstrument = NIL;
  549.         InstrObj->UpToDate = False;
  550.         InstrObj->InstrWindow = NIL;
  551.         InstrObj->CodeCenter = CodeCenter;
  552.         InstrObj->MainWindow = MainWindow;
  553.         InstrObj->InstrList = InstrList;
  554.  
  555.         *ObjectOut = InstrObj;
  556.         return eFileLoadNoError;
  557.     }
  558.  
  559.  
  560. /* write the data in the object to the file. */
  561. FileLoadingErrors            InstrObjectWriteDataOut(InstrObjectRec* InstrObj,
  562.                                                 struct BufferedOutputRec* Output)
  563.     {
  564.         char*                                StringTemp;
  565.  
  566.         CheckPtrExistence(InstrObj);
  567.         CheckPtrExistence(Output);
  568.  
  569.         /*   1-byte format version number */
  570.         /*       should be 1 */
  571.         if (!WriteBufferedUnsignedChar(Output,1))
  572.             {
  573.                 return eFileLoadDiskError;
  574.             }
  575.  
  576.         /*   2-byte little endian window X location (signed; origin at top-left of screen) */
  577.         /* the way we're doing this, if the window is open when we write the data out, */
  578.         /* then the most recent location of the window will not be saved. */
  579.         if (!WriteBufferedSignedShortLittleEndian(Output,InstrObj->SavedWindowXLoc))
  580.             {
  581.                 return eFileLoadDiskError;
  582.             }
  583.  
  584.         /*   2-byte little endian window Y location */
  585.         if (!WriteBufferedSignedShortLittleEndian(Output,InstrObj->SavedWindowYLoc))
  586.             {
  587.                 return eFileLoadDiskError;
  588.             }
  589.  
  590.         /*   2-byte little endian window width */
  591.         if (!WriteBufferedSignedShortLittleEndian(Output,InstrObj->SavedWindowWidth))
  592.             {
  593.                 return eFileLoadDiskError;
  594.             }
  595.  
  596.         /*   2-byte little endian window height */
  597.         if (!WriteBufferedSignedShortLittleEndian(Output,InstrObj->SavedWindowHeight))
  598.             {
  599.                 return eFileLoadDiskError;
  600.             }
  601.  
  602.         /*   4-byte little endian name string length */
  603.         StringTemp = InstrObjectGetNameCopy(InstrObj);
  604.         if (StringTemp == NIL)
  605.             {
  606.                 return eFileLoadOutOfMemory;
  607.             }
  608.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  609.             {
  610.                 ReleasePtr(StringTemp);
  611.                 return eFileLoadDiskError;
  612.             }
  613.  
  614.         /*   n-byte name string (line feed = 0x0a) */
  615.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  616.             {
  617.                 ReleasePtr(StringTemp);
  618.                 return eFileLoadDiskError;
  619.             }
  620.         ReleasePtr(StringTemp);
  621.  
  622.         /*   4-byte little endian instrument definition length */
  623.         StringTemp = InstrObjectGetDefinitionCopy(InstrObj);
  624.         if (StringTemp == NIL)
  625.             {
  626.                 return eFileLoadOutOfMemory;
  627.             }
  628.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  629.             {
  630.                 ReleasePtr(StringTemp);
  631.                 return eFileLoadDiskError;
  632.             }
  633.  
  634.         /*   n-byte instrument definition string (line feed = 0x0a) */
  635.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  636.             {
  637.                 ReleasePtr(StringTemp);
  638.                 return eFileLoadDiskError;
  639.             }
  640.         ReleasePtr(StringTemp);
  641.  
  642.         return eFileLoadNoError;
  643.     }
  644.  
  645.  
  646. /* mark the instrument object as saved */
  647. void                                    InstrObjectMarkAsSaved(InstrObjectRec* InstrObj)
  648.     {
  649.         CheckPtrExistence(InstrObj);
  650.         if (InstrObj->InstrWindow != NIL)
  651.             {
  652.                 InstrWindowWritebackModifiedData(InstrObj->InstrWindow);
  653.             }
  654.         InstrObj->DataModified = False;
  655.     }
  656.